home *** CD-ROM | disk | FTP | other *** search
/ Programming Windows 95 / Programming Windows 95.iso / code / CHAP07 / BOUNCE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-01  |  4.9 KB  |  147 lines

  1. /*---------------------------------------
  2.    BOUNCE.C -- Bouncing Ball Program
  3.                (c) Charles Petzold, 1996
  4.   ---------------------------------------*/
  5.  
  6. #include <windows.h>
  7.  
  8. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
  9.  
  10. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
  11.                     PSTR szCmdLine, int iCmdShow)
  12.      {
  13.      static char szAppName[] = "Bounce" ;
  14.      HWND        hwnd ;
  15.      MSG         msg ;
  16.      WNDCLASSEX  wndclass ;
  17.  
  18.      wndclass.cbSize        = sizeof (wndclass) ;
  19.      wndclass.style         = CS_HREDRAW | CS_VREDRAW ;
  20.      wndclass.lpfnWndProc   = WndProc ;
  21.      wndclass.cbClsExtra    = 0 ;
  22.      wndclass.cbWndExtra    = 0 ;
  23.      wndclass.hInstance     = hInstance ;
  24.      wndclass.hIcon         = LoadIcon (NULL, IDI_APPLICATION) ;
  25.      wndclass.hCursor       = LoadCursor (NULL, IDC_ARROW) ;
  26.      wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH) ;
  27.      wndclass.lpszMenuName  = NULL ;
  28.      wndclass.lpszClassName = szAppName ;
  29.      wndclass.hIconSm       = LoadIcon (NULL, IDI_APPLICATION) ;
  30.  
  31.      RegisterClassEx (&wndclass) ;
  32.  
  33.      hwnd = CreateWindow (szAppName, "Bouncing Ball",
  34.                           WS_OVERLAPPEDWINDOW,
  35.                           CW_USEDEFAULT, CW_USEDEFAULT,
  36.                           CW_USEDEFAULT, CW_USEDEFAULT,
  37.                           NULL, NULL, hInstance, NULL) ;
  38.  
  39.      if (!SetTimer (hwnd, 1, 50, NULL))
  40.           {
  41.           MessageBox (hwnd, "Too many clocks or timers!",
  42.                       szAppName, MB_ICONEXCLAMATION | MB_OK) ;
  43.           return FALSE ;
  44.           }
  45.  
  46.      ShowWindow (hwnd, iCmdShow) ;
  47.      UpdateWindow (hwnd) ;
  48.  
  49.      while (GetMessage (&msg, NULL, 0, 0))
  50.           {
  51.           TranslateMessage (&msg) ;
  52.           DispatchMessage (&msg) ;
  53.           }
  54.      return msg.wParam ;
  55.      }
  56.  
  57. LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  58.      {
  59.      static HBITMAP hBitmap ;
  60.      static int     cxClient, cyClient, xCenter, yCenter, cxTotal, cyTotal,
  61.                     cxRadius, cyRadius, cxMove, cyMove, xPixel, yPixel ;
  62.      HBRUSH         hBrush ;
  63.      HDC            hdc, hdcMem ;
  64.      int            iScale ;
  65.  
  66.      switch (iMsg)
  67.           {
  68.           case WM_CREATE :
  69.                hdc = GetDC (hwnd) ;
  70.                xPixel = GetDeviceCaps (hdc, ASPECTX) ;
  71.                yPixel = GetDeviceCaps (hdc, ASPECTY) ;
  72.                ReleaseDC (hwnd, hdc) ;
  73.                return 0 ;
  74.  
  75.           case WM_SIZE :
  76.                xCenter = (cxClient = LOWORD (lParam)) / 2 ;
  77.                yCenter = (cyClient = HIWORD (lParam)) / 2 ;
  78.  
  79.                iScale = min (cxClient * xPixel, cyClient * yPixel) / 16 ;
  80.  
  81.                cxRadius = iScale / xPixel ;
  82.                cyRadius = iScale / yPixel ;
  83.  
  84.                cxMove = max (1, cxRadius / 2) ;
  85.                cyMove = max (1, cyRadius / 2) ;
  86.  
  87.                cxTotal = 2 * (cxRadius + cxMove) ;
  88.                cyTotal = 2 * (cyRadius + cyMove) ;
  89.  
  90.                if (hBitmap)
  91.                     DeleteObject (hBitmap) ;
  92.  
  93.                hdc = GetDC (hwnd) ;
  94.                hdcMem = CreateCompatibleDC (hdc) ;
  95.                hBitmap = CreateCompatibleBitmap (hdc, cxTotal, cyTotal) ;
  96.                ReleaseDC (hwnd, hdc) ;
  97.  
  98.                SelectObject (hdcMem, hBitmap) ;
  99.                Rectangle (hdcMem, -1, -1, cxTotal + 1, cyTotal + 1) ;
  100.  
  101.                hBrush = CreateHatchBrush (HS_DIAGCROSS, 0L) ;
  102.                SelectObject (hdcMem, hBrush) ;
  103.                SetBkColor (hdcMem, RGB (255, 0, 255)) ;
  104.                Ellipse (hdcMem, cxMove, cyMove, cxTotal - cxMove,
  105.                                                 cyTotal - cyMove) ;
  106.                DeleteDC (hdcMem) ;
  107.                DeleteObject (hBrush) ;
  108.                return 0 ;
  109.  
  110.           case WM_TIMER :
  111.                if (!hBitmap)
  112.                     break ;
  113.  
  114.                hdc = GetDC (hwnd) ;
  115.                hdcMem = CreateCompatibleDC (hdc) ;
  116.                SelectObject (hdcMem, hBitmap) ;
  117.  
  118.                BitBlt (hdc, xCenter - cxTotal / 2,
  119.                             yCenter - cyTotal / 2, cxTotal, cyTotal,
  120.                        hdcMem, 0, 0, SRCCOPY) ;
  121.  
  122.                ReleaseDC (hwnd, hdc) ;
  123.                DeleteDC (hdcMem) ;
  124.  
  125.                xCenter += cxMove ;
  126.                yCenter += cyMove ;
  127.  
  128.                if ((xCenter + cxRadius >= cxClient) ||
  129.                    (xCenter - cxRadius <= 0))
  130.                          cxMove = -cxMove ;
  131.  
  132.                if ((yCenter + cyRadius >= cyClient) ||
  133.                    (yCenter - cyRadius <= 0))
  134.                          cyMove = -cyMove ;
  135.                return 0 ;
  136.  
  137.           case WM_DESTROY :
  138.                if (hBitmap)
  139.                     DeleteObject (hBitmap) ;
  140.  
  141.                KillTimer (hwnd, 1) ;
  142.                PostQuitMessage (0) ;
  143.                return 0 ;
  144.           }
  145.      return DefWindowProc (hwnd, iMsg, wParam, lParam) ;
  146.      }
  147.